#pragma once
#ifndef __VERTEXSTREAM_H__
#define __VERTEXSTREAM_H__

#include "Utility.h"

#include "../util/PreDeclare.h"

namespace WindGE
{
	enum EVertexStreamType
	{
		e_vst_unkown = 0,
		e_vst_graphics,
		e_vst_texcoord,
		e_vst_animation,
		e_vst_instance,
		e_vst_user0,
		e_vst_index,
	};

	struct VertexGraphics
	{
		VertexGraphics() { memset(this, 0, sizeof(VertexGraphics)); }

		float posX, posY, posZ;
		float normalX, normalY, normalZ;
		float color0R, color0G, color0B, color0A;
		float color1R, color1G, color1B, color1A;
	};

	struct VertexTexcoord
	{
		VertexTexcoord() { memset(this, 0, sizeof(VertexTexcoord)); }

		float tangentX, tangentY, tangentZ;
		float texU0, texV0;
		float texU1, texV1;
		float texU2, texV2;
		float texU3, texV3;
	};

	struct VertexAnimation
	{
		VertexAnimation() { memset(this, 0, sizeof(VertexAnimation)); }

		float weights[3];
		unsigned char boneIndices[4];
	};

	struct VertexInstance
	{
		VertexInstance() { memset(this, 0, sizeof(VertexInstance)); }

		float worldmat0[4];
		float worldmat1[4];
		float worldmat2[4];
		float worldmat3[4];
		float colorR, colorG, colorB, colorA;
	};

	struct VertexUser0
	{
		VertexUser0() { memset(this, 0, sizeof(VertexUser0)); }

		float boundsX, boundsY;
	};

	class WIND_CORE_API VertexStream
	{
	public:
		VertexStream();
		VertexStream(const VertexStream& vertexStream);

		~VertexStream();

		bool init(const std::string& name, unsigned int stride, unsigned int count);
		bool reinit(unsigned int num);

		bool save(std::ostream& outFile);
		bool load(std::istream& inFile);

		//realloc is expensive, please use it carefully
		void add(void* vertBuff);
		void add(void* vertBuff, unsigned int num);
		
		void set(void* vertBuff, unsigned int offset);
		void set(void* vertBuff, unsigned int offset, unsigned int num);

		inline const std::string& name() const		{ return name_;					}
		inline void* buffer()			 const		{ return buffer_;				}
		inline unsigned int size()		 const		{ return stride_*count_;		}
		inline unsigned int count()		 const		{ return count_;				}
		inline unsigned int stride()	 const		{ return stride_;				}
		inline bool is_index()			 const		{ return type_ == e_vst_index;	}
		inline EVertexStreamType type()  const		{ return type_;					}
		inline void set_type(EVertexStreamType t)	{ type_ = t;					}

	protected:
		std::string				name_;
		void*					buffer_;
		unsigned int			stride_;
		unsigned int			count_;
		unsigned int			offset_;
		EVertexStreamType		type_;
	};

}//end namespace WindGE

#endif // !__VERTEXSTREAM_H__
